home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 31 / Amiga Format CD31 (1998-09-02)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1998-10].iso / -seriously_amiga- / hardware / transadf / source / defl_disk.c < prev    next >
C/C++ Source or Header  |  1998-07-20  |  8KB  |  243 lines

  1. /* defl_disk.c - Delfate a disk into a compressed file
  2. ** Copyright (C) 1997,1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <devices/trackdisk.h>
  22. #include <dos/dos.h>
  23. #include <clib/exec_protos.h>
  24. #include <clib/dos_protos.h>
  25.  
  26. #include "zlib.h"
  27.  
  28. #include "defl_disk.h"
  29. #include "main.h"
  30. #include "mem_chunks.h"
  31. #include "td.h"
  32. #include "util.h"
  33. #include "errors.h"
  34.  
  35.  
  36. #define DD_TBTRACKS 1                           /* Tracks in dd_TrackBuf */
  37. #define DD_TBSIZE   (DD_TBTRACKS * TRACK_SIZE)  /* Bytes in dd_TrackBuf  */
  38. #define DD_FBSIZE   (32*1024)                   /* Bytes in dd_FileBuf   */
  39.  
  40. UBYTE *dd_TrackBuf;    /* Our input buffer - reads from disk. */
  41. UBYTE *dd_FileBuf;     /* Our output buffer - writes to file. */
  42.  
  43.  
  44. /*
  45. ** Deflate a disk into a file.
  46. ** Expects all fields of adfPkt to be set.
  47. */
  48. void deflDisk (struct ADF_Packet *adfPkt, ULONG deflLevel, STRPTR origName,
  49.                ULONG fileType)
  50. {
  51.   static z_stream defl_stream;
  52.   ULONG nextTrack, CRC, USize, CSize;
  53.   LONG DOSError;
  54.   BYTE TDError;
  55.   int zerr, ocnt, deflg, winbits;
  56.   
  57.   
  58.   /* Output info header */
  59.   FPrintf (StdOut, "Deflating from TrackDisk Unit %ld (DF%ld:) to %s.\n",
  60.                    adfPkt->diskUnit,
  61.                    adfPkt->diskUnit,
  62.                    adfPkt->ADFileName);
  63.   
  64.   FPrintf (StdOut, "Starting at track %ld, Ending at track %ld.\n",
  65.                    (adfPkt->startTrack>>1),
  66.                    (adfPkt->endTrack>>1));
  67.   
  68.   FPuts (StdOut, "Compressing disk as a ");
  69.   switch (fileType) {
  70.   case FT_ZLIB:      FPuts (StdOut, "ZLib");  break;
  71.   case FT_GZIP:      FPuts (StdOut, "GZip");  break;
  72.   case FT_PKZIP:     
  73.   case FT_PKZIP_ADD: FPuts (StdOut, "PKZip"); break;
  74.   }
  75.   FPuts (StdOut, " file.\n");
  76.   
  77.   
  78.   /* Allocate the buffers */
  79.   dd_TrackBuf = (UBYTE *)myAllocMem (DD_TBSIZE, MEMF_CLEAR);
  80.   dd_FileBuf  = (UBYTE *)myAllocMem (DD_FBSIZE, MEMF_CLEAR);
  81.   if (!dd_TrackBuf || !dd_FileBuf)
  82.   {
  83.     /* No Memory */
  84.     FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  85.     cleanExit(RETURN_FAIL, ERROR_NO_FREE_STORE);
  86.   }
  87.   
  88.   /* Output the file header */
  89.   if (writeHead (adfPkt->ADFile, origName, fileType) == FALSE)
  90.   {
  91.     DOSError = IoErr();
  92.     
  93.     FPrintf (StdErr, "%s: Error - Couldn't write file header.\n",ProgName);
  94.     
  95.     if (DOSError)
  96.       reportDOSError(DOSError);
  97.     
  98.     cleanExit (RETURN_FAIL, NULL);
  99.   }
  100.   
  101.   /* Initialise the z_stream */
  102.   if (fileType == FT_ZLIB) winbits = 15;
  103.   else winbits = -15; /* windowBits is passed < 0 to suppress zlib header */    
  104.   defl_stream.zalloc = Z_NULL;
  105.   defl_stream.zfree  = Z_NULL;
  106.   defl_stream.opaque = Z_NULL;
  107.   zerr = deflateInit2 (&defl_stream, deflLevel,
  108.                        Z_DEFLATED, winbits, 8, 0);
  109.   if (zerr != Z_OK)
  110.   {
  111.     FPrintf (StdErr, "%s: Deflate Init Error - ", ProgName);
  112.     reportZLibError (zerr);
  113.     if (defl_stream.msg) FPrintf (StdErr, "\t(%s)\n", defl_stream.msg);
  114.     cleanExit (RETURN_FAIL, NULL);
  115.   }
  116.     
  117.   /* Start deflateing */
  118.   defl_stream.avail_in  = 0;           /* Input buffer is empty    */
  119.   defl_stream.next_out  = dd_FileBuf;  /* Pointer to output buffer */
  120.   defl_stream.avail_out = DD_FBSIZE;   /* output buffer is empty   */
  121.   deflg = Z_NO_FLUSH;
  122.   CRC = crc32 (NULL, Z_NULL, 0);       /* Initialise the CRC       */
  123.   nextTrack = adfPkt->startTrack;
  124.   while (1)
  125.   {
  126.     if (defl_stream.avail_in == 0)  /* Input is empty */
  127.       if (nextTrack <= adfPkt->endTrack)
  128.       {
  129.         /* Update progress report */
  130.         FPuts (StdOut, "\rReading   ");
  131.         FPUTS_TS (nextTrack, StdOut);
  132.         Flush (StdOut);
  133.         
  134.         /* Fill the input buffer from disk */
  135.         TDError = readTrack (dd_TrackBuf, DD_TBTRACKS, nextTrack, 
  136.                              adfPkt->diskReq);
  137.         if (TDError)
  138.         {
  139.           FPutC (StdOut, '\n');
  140.           FPrintf (StdErr, "%s: Error reading from DF%ld: - ",
  141.                            ProgName, adfPkt->diskUnit);
  142.           reportTDError (TDError);
  143.           deflateEnd (&defl_stream);
  144.           cleanExit (RETURN_FAIL, NULL);
  145.         }
  146.         
  147.         nextTrack++;
  148.         defl_stream.next_in  = dd_TrackBuf;
  149.         defl_stream.avail_in = DD_TBSIZE;
  150.       }
  151.     
  152.     if (defl_stream.avail_in == 0)  /* Still zero - no more input */
  153.       deflg = Z_FINISH;
  154.     else
  155.       /* New data - Update the CRC */
  156.       CRC = crc32 (CRC, dd_TrackBuf ,defl_stream.avail_in);
  157.     
  158.     /* Fill the output buffer with deflated data, and keep filling */
  159.     /* it until no more inflated data exists in the input buffer.  */
  160.     while (1)
  161.     {
  162.       /* Check for Control-C break */
  163.       if (CTRL_C)
  164.       {
  165.         FPutC (StdOut, '\n');
  166.         FPrintf (StdErr, "%s - %s\n", breakText, ProgName);
  167.         deflateEnd (&defl_stream);
  168.         cleanExit (RETURN_WARN, NULL);
  169.       }
  170.       
  171.       /* Upate progress report */
  172.       FPuts (StdOut, "\rDeflating ");
  173.       Flush (StdOut);
  174.       
  175.       zerr = deflate (&defl_stream, deflg);
  176.       if (zerr < Z_OK)
  177.       {
  178.         FPutC (StdOut, '\n');
  179.         FPrintf (StdErr, "%s: Deflate error - ", ProgName);
  180.         reportZLibError (zerr);
  181.         if (defl_stream.msg) FPrintf (StdErr, "\t%s\n", defl_stream.msg);
  182.         deflateEnd (&defl_stream);
  183.         cleanExit (RETURN_FAIL, NULL);
  184.       }
  185.       
  186.       /* Flush the output buffer */
  187.       ocnt = DD_FBSIZE - defl_stream.avail_out;
  188.       if (ocnt) 
  189.       {
  190.         if ( Write (adfPkt->ADFile, dd_FileBuf, ocnt) != ocnt)
  191.         {
  192.           DOSError = IoErr();
  193.           
  194.           FPutC (StdOut, '\n');
  195.           FPrintf (StdErr, "%s: Error writing deflated data - ", ProgName);
  196.           reportDOSError(DOSError);
  197.           
  198.           cleanExit (RETURN_FAIL, DOSError);
  199.         }
  200.       }
  201.       defl_stream.next_out  = dd_FileBuf;
  202.       defl_stream.avail_out = DD_FBSIZE;
  203.       
  204.       if ((ocnt != DD_FBSIZE) || (zerr == Z_STREAM_END))
  205.         /* Last deflate() did not completely fill the output buffer,  */
  206.         /* thus no more data is pending, or we reached the end of the */
  207.         /* compressed data stream.                                    */
  208.         break;
  209.     }
  210.     if (zerr == Z_STREAM_END) break;
  211.   }
  212.   USize = defl_stream.total_in;
  213.   CSize = defl_stream.total_out;
  214.   
  215.   FPrintf (StdOut, "\rDeflated: %ld ==> %ld (%ld%%).   ",
  216.                    USize, CSize, ((CSize * 100) / USize));
  217.   Flush (StdOut);
  218.   
  219.   /* End the deflate process */
  220.   zerr = deflateEnd (&defl_stream);
  221.   if (zerr != Z_OK)
  222.   {
  223.     FPutC (StdOut, '\n');
  224.     FPrintf (StdErr, "%s: Deflate End Error - ", ProgName);
  225.     reportZLibError (zerr);
  226.     if (defl_stream.msg) FPrintf (StdErr, "\t(%s)\n", defl_stream.msg);
  227.     cleanExit (RETURN_FAIL, NULL);
  228.   }
  229.   
  230.   /* Finish the file */
  231.   if ( finishFile (adfPkt->ADFile, CRC, CSize, USize, fileType) == FALSE)
  232.   {
  233.     FPutC (StdOut, '\n');
  234.     FPrintf (StdErr, "%s: Error - Couldn't finish output file correctly.\n",
  235.                      ProgName);
  236.     cleanExit (RETURN_FAIL, NULL);
  237.   }
  238.   
  239.   /* Free and clear buffers */
  240.   myFreeMem (dd_TrackBuf);
  241.   myFreeMem (dd_FileBuf);
  242. }
  243.